package erfgame.frontend.desktop.controller;

import java.awt.Container;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.JComponent;
import javax.swing.SwingUtilities;

import erfgame.core.Operation;
import erfgame.core.OperationResultListener;
import erfgame.core.PollingExecutor;

import erfgame.frontend.desktop.view.ViewActionListener;
import erfgame.frontend.desktop.view.main.MainView;
import erfgame.frontend.desktop.view.operation.OperationViewController;

public class MainController extends AbstractController {
	
	private static final Logger log = Logger.getLogger( MainController.class.getName() );
	
	private Container mainContainer;
	private Object mainConstraints;
	
	private CreateWorldController createWorldController;
	private SelectViewWorldController selectViewWorldController;
	
	private PollingExecutor executor;
	
	private MainView mainView;
	
	public MainController( 
			CreateWorldController createWorldController, 
			SelectViewWorldController selectViewWorldController
	) {
		this.createWorldController = createWorldController;
		this.selectViewWorldController = selectViewWorldController;
		
		ControllerCompletionListener completionListener = new ControllerCompletionListener() {
			public void controllerCompleted(Object source) {
				showMainView();
			}
		};
		this.createWorldController.addControllerCompletionListener( completionListener );
		this.selectViewWorldController.addControllerCompletionListener( completionListener );
		
		this.mainView = new MainView();
		this.mainView.addViewActionListener( new ViewActionListener() {
			public void actionPerformed(
					Object source, 
					int actionType,
					Object operation) {
				switch( actionType ) {
				case MainView.ACTION_TYPE_CREATE_WORLD:
					displayCreateWorldView();
					break;
				case MainView.ACTION_TYPE_VIEW_WORLD:
					displaySelectViewWorldView();
					break;
				case MainView.ACTION_TYPE_EXIT:
					fireControllerCompleted();
					break;
				}
			}
		});
	}
	
	public void setExecutor(PollingExecutor executor) {
		this.executor = executor;
	}
	
	public void start( Container mainContainer, Object mainConstraints ) {
		this.mainContainer = mainContainer;
		this.mainConstraints = mainConstraints;		
		this.mainView.init();
		showMainView();
	}

	public void showMainView() {
		SwingUtilities.invokeLater( new Runnable() {
			public void run() {
				MainController.this.mainContainer.removeAll();
				MainController.this.mainContainer.add( 
						MainController.this.mainView.getComponent(), 
						MainController.this.mainConstraints 
				);
				MainController.this.mainContainer.repaint();		
			}
		});
	}
	
	public void displayCreateWorldView() {
		this.createWorldController.start( this.mainContainer, this.mainConstraints );
	}
	
	public void displaySelectViewWorldView() {
		this.selectViewWorldController.start( this.mainContainer, this.mainConstraints );
	}

	@Override
	@SuppressWarnings(value="unchecked")
	public void close() {
		super.close();
		this.createWorldController.close();
		this.selectViewWorldController.close();
		if( executor != null ) {
			Operation<Void, RuntimeException> operation = this.executor.stopPolling();
			OperationViewController.showOperationDialog(
					operation, 
					(JComponent)mainContainer, 
					new OperationResultListener<Void, RuntimeException>() {

						public void failure(RuntimeException error) {
							log.log(Level.WARNING, "error closing down", error);
						}

						public void success(Void result) {
							fireControllerCompleted();
						}
					}
			);
		}
	}
}
